package com.mindmap.ui;

import com.mindmap.model.MindMap;
import com.mindmap.model.Node;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.util.List;
import java.util.ArrayList;
import java.awt.geom.Path2D;

public class DrawingPanel extends JPanel {
    private MainFrame mainFrame;
    private MindMap mindMap;

    private static final Color NODE_COLOR = new Color(220, 240, 255);
    private static final Color SELECTED_NODE_COLOR = new Color(180, 220, 255);
    private static final Color LINE_COLOR = new Color(80, 80, 80);
    private static final Font NODE_FONT = new Font("微软雅黑", Font.PLAIN, 14);

    public DrawingPanel(MainFrame mainFrame) {
        this.mainFrame = mainFrame;
        setBackground(Color.WHITE);
        
        if (mindMap != null) {
            mindMap.setPanelSize(getSize());
        }

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                handleMouseClick(e);
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        if (mindMap != null && mindMap.getRoot() != null) {
            drawNode(g2d, mindMap.getRoot());
        }
    }

    private void drawNode(Graphics2D g2d, Node node) {
        // 绘制连接线 - 改为曲线
        if (node != mindMap.getRoot()) {
            g2d.setColor(new Color(100, 100, 100));
            g2d.setStroke(new BasicStroke(1.8f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            
            Point start = node.getParent().getConnectionPoint(node);
            Point end = node.getConnectionPoint(node.getParent());
            
            // 绘制贝塞尔曲线
            int ctrlX = (start.x + end.x) / 2;
            int ctrlY = start.y;
            if (Math.abs(start.y - end.y) > 50) {
                ctrlY = (start.y + end.y) / 2;
            }
            
            Path2D path = new Path2D.Double();
            path.moveTo(start.x, start.y);
            path.quadTo(ctrlX, ctrlY, end.x, end.y);
            g2d.draw(path);
        }

        // 绘制节点
        Rectangle bounds = node.getBounds();
        GradientPaint gradient;
        if (node.isSelected()) {
            gradient = new GradientPaint(
                bounds.x, bounds.y, new Color(180, 220, 255),
                bounds.x, bounds.y + bounds.height, new Color(150, 200, 250)
            );
        } else {
            gradient = new GradientPaint(
                bounds.x, bounds.y, new Color(220, 240, 255),
                bounds.x, bounds.y + bounds.height, new Color(200, 230, 250)
            );
        }
        g2d.setPaint(gradient);
        g2d.fillRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 12, 12);
        
        // 绘制边框
        g2d.setColor(new Color(80, 80, 80));
        g2d.setStroke(new BasicStroke(1.5f));
        g2d.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 12, 12);

        // 绘制文本
        g2d.setFont(NODE_FONT);
        FontMetrics fm = g2d.getFontMetrics();
        String text = node.getText();
        
        // 文本自动换行
        List<String> lines = wrapText(text, fm, bounds.width - 15);
        
        int lineHeight = fm.getHeight();
        int totalHeight = lines.size() * lineHeight;
        int y = bounds.y + (bounds.height - totalHeight) / 2 + fm.getAscent();
        
        g2d.setColor(Color.BLACK);
        for (String line : lines) {
            int textWidth = fm.stringWidth(line);
            int x = bounds.x + (bounds.width - textWidth) / 2;
            g2d.drawString(line, x, y);
            y += lineHeight;
        }

        // 绘制子节点
        for (Node child : node.getChildren()) {
            drawNode(g2d, child);
        }
    }

    private List<String> wrapText(String text, FontMetrics fm, int maxWidth) {
        List<String> lines = new ArrayList<>();
        if (text == null || text.isEmpty()) return lines;
        
        // 处理中文文本
        if (containsChinese(text)) {
            int charPerLine = maxWidth / fm.charWidth('中');
            int start = 0;
            while (start < text.length()) {
                int end = Math.min(start + charPerLine, text.length());
                lines.add(text.substring(start, end));
                start = end;
            }
            return lines;
        }
        
        // 处理英文文本
        String[] words = text.split("\\s+");
        StringBuilder currentLine = new StringBuilder();
        
        for (String word : words) {
            String testLine = currentLine.length() == 0 ? word : currentLine + " " + word;
            if (fm.stringWidth(testLine) <= maxWidth) {
                currentLine.append(currentLine.length() == 0 ? word : " " + word);
            } else {
                if (currentLine.length() > 0) {
                    lines.add(currentLine.toString());
                }
                currentLine = new StringBuilder(word);
            }
        }
        
        if (currentLine.length() > 0) {
            lines.add(currentLine.toString());
        }
        
        return lines;
    }
    private boolean containsChinese(String text) {
        return text.matches(".*[\u4e00-\u9fa5].*");
    }
    private void handleMouseClick(MouseEvent e) {
        if (mindMap == null) return;

        Point clickPoint = e.getPoint();
        Node clickedNode = mindMap.findNodeAt(clickPoint);

        if (clickedNode != null) {
            mindMap.setSelectedNode(clickedNode);
            repaint();
        } else {
            // 点击空白处取消选择
            if (mindMap.getSelectedNode() != null) {
                mindMap.setSelectedNode(null);
                repaint();
            }
        }
    }

    public void setMindMap(MindMap mindMap) {
        this.mindMap = mindMap;
    }

    public void exportToImage(File file, String format) {
        BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();
        paint(g2d);
        g2d.dispose();

        try {
            ImageIO.write(image, format, file);
            JOptionPane.showMessageDialog(this, "导出成功!");
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, "导出失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
}
